home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / ns_16550.zip / FACT.C < prev    next >
Text File  |  1991-07-20  |  14KB  |  435 lines

  1. /*         FFFFFFF      A          CCCCCC    TTTTTTTTTTT            CCCCCC
  2.  *         F           A A        C               T                C
  3.  *         FFFFF      A   A       C               T                C
  4.  *         F         A AAA A      C               T                C
  5.  *         F        A       A     C               T       ..       C
  6.  *         F       A         A     CCCCCC         T       ..        CCCCCC
  7.  *
  8.  *            FACT.C -- FIFO Asynchronous Communication Test Program for
  9.  *                      NS16550 and NS16552 UARTs
  10.  *
  11.  *            Greg DeJager            Ver 1.0         1/31/89
  12.  *
  13.  *            Adapted from LBT.C -- LoopBack Test  Rev 1.1
  14.  *            Developed By:   Brian A. Berg
  15.  *                            Berg Software Design
  16.  *                            October 1988
  17.  *
  18.  */
  19.                
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <conio.h>
  23. #include <dos.h>
  24. #include "stdhdr.h"
  25. #include "serio.h"
  26.  
  27. /* define some macros for use herein */
  28. /*   program test name for user prompt and help screen */
  29. #define TESTNAME        "NS16550/NS16552 FIFO Asynchronous Communications Test (FACT)"
  30. /*   clear the RBR, LSR and IIR registers (used at start and before exit) */
  31. #define CLEAR_REGS()    ((void)rdRBR(), (void)rdRBR(), \
  32.              (void)rdLSR(), (void)rdIIR(), (void)wrMCR(0), \
  33.              (void)wrFCR(CLR_FIFO))
  34.  
  35. /*   GET ctrl-break/ctrl-c checking flag status via "INT 21H" */
  36. #define GETBRK()    (regs.h.ah = 0x33, regs.h.al = 0, \
  37.              intdos(®s, ®s), regs.h.dl)
  38. /*   SET ctrl-break/ctrl-c checking flag to argument via "INT 21H" */
  39. #define SETBRK(brk)    (regs.h.ah = 0x33, regs.h.al = 1, \
  40.              regs.h.dl = (brk), intdos(®s, ®s))
  41.  
  42. /* COMx-dependent parameters */
  43. UINT comvnum[COM_CNT] = {0x0C, 0x0B, 0x0B};        /* int. vector nos. for COMx */
  44. UINT uartbadd[COM_CNT] = {0x3F8, 0x2F8, 0x3220};   /* UART base adds. for COMx */
  45. UINT picmsk[COM_CNT] = {0xEF, 0xF7, 0xF7};         /* PIC masks for COMx: IRQ4,3 */
  46.  
  47. /* declare parameters and default values; override via invocation line args. */
  48. /*   argument 1: COM number */
  49. int com = COM_DEF;
  50. UINT ivnum;            /* int. vector number (set as comvnum[com-1]) */
  51. UINT ubase;            /* UART base address (set as uartbadd[com-1]) */
  52. /*   argument 2: baud rate divisor */
  53. int baudiv = BAUDIV_DEF;
  54.  
  55. UCHAR bytwr = 0;        /* write byte counter (goes from 0 to 255) */
  56. UCHAR bytrd = 0;        /* read byte counter (goes from 0 to 255) */
  57.  
  58. UCHAR iir, lsr;                 /* storage for IIR and LSR */
  59. UCHAR bytin;                    /* input byte storage */
  60.  
  61. UINT errflag = FALSE;           /* error indication and ID */
  62.  
  63. /* storage for original environment parameters */
  64. void far *savect;    /* interrupt vector */
  65. UCHAR savbrk;        /* ctrl-break flag */
  66. UINT savmsk;        /* PIC mask */
  67. UCHAR savier;        /* IER register */
  68. UCHAR savlcr;        /* LCR register */
  69. UCHAR savmcr;        /* MCR register */
  70. UCHAR savdll;        /* DLL register */
  71. UCHAR savdlm;        /* DLM register */
  72.  
  73. CNVTR cnvtr;            /* handy union for data type conversions */
  74. union REGS regs;        /* 16- and 8-bit registers for intdos() */
  75. int finit = FALSE;        /* boolean for program termination */
  76.  
  77. /* globals which control the tick mark on the screen */
  78. int tick = FALSE;        /* boolean for display of "tick" on CRT */
  79. int tick_ff = 0;        /* tick flip-flop (either 0 or 1) */
  80. int bytick = 0;            /* helps determine when to set tick boolean */
  81. UCHAR *tickstr[] = {"\b*", "\b$"};      /* "tick" mark strings */
  82.  
  83. /* Routines contained herein: */
  84. void main(int, char **);        /* main program */
  85. void interrupt far serint(void);    /* serial interrupt handler */
  86. void procarg(int, char **);        /* process invocation arguments */
  87. void savepar(void);            /* save our environment parameters */
  88. void rstrpar(void);            /* restore our environment parameters */
  89. void dspstr(UCHAR *);                   /* display a string to console */
  90. void usage(void);                       /* display usage info and exit */
  91.  
  92. /*
  93.  *    main(): main program
  94.  */
  95.  
  96. void main(argc, argv)
  97.    int argc;
  98.    char **argv;
  99. {
  100.     /* process invocation args., and set up int vector no. and UART base add */
  101.     procarg(argc, argv);    /* get com# and baudrate from argument string */
  102.     CLEAR_REGS();           /* clear RBR, LSR, IIR, MCR, and FIFOs */
  103.     savepar();              /* save our environment parameters */
  104.  
  105.     /* set baud rate */
  106.     wrLCR(0x80);                    /* set DLAB */
  107.     cnvtr.intval[0] = baudiv;
  108.     outp(DLL, cnvtr.chrval[0]);
  109.     outp(DLM, cnvtr.chrval[1]);
  110.     wrLCR(0x0B);                    /* 8 data, 1 stop, odd parity */
  111.  
  112.     printf("\n\n          %s\n\n",TESTNAME);    /*startup message*/
  113.  
  114.     /* wait loop to insure other machine has cleared its registers */
  115.     printf("\nHit a key when other program has been started.\n\n");
  116.     while( !(kbhit() && getch()) );
  117.  
  118.     /* set up registers for our environment */
  119.     wrFCR(CLR_FIFO);        /* clear transmitter and receiver FIFOs */
  120.     wrFCR(FIFO_EN);         /* enable FIFOs, set Rx trigger at 14 bytes */
  121.     if ( (rdIIR() & 0xc0) != 0xc0)          /* ensure FIFOs present */
  122.     {
  123.         printf("\nFatal Error.  FIFOs not present\n");
  124.         errflag = ENDPROG;
  125.     }
  126.     wrMCR(OUT2);            /* enable PIC interrupt (OUT2) */
  127.     wrIER(IER_VAL1);        /* Enable LSI and RDAI */
  128.     wrMCR(0x0a);            /* Assert RTS (and OUT2) */
  129.  
  130.     printf("Waiting for first 'Request To Send' from other machine...\n\n");
  131.     while (!(rdMSR() & CTS));     /* wait for other machine to assert RTS */
  132.  
  133.     printf("\n\nHit non-control key to stop:  ");
  134.  
  135.     /* Enable Tx interupts; loop until int. handler finished or any key struck */
  136.     wrIER(IER_VAL2);
  137.     while (!errflag)
  138.     {
  139.         if (kbhit() && getch())
  140.             errflag = ENDPROG;
  141.         if (tick)                       /* display tick mark */
  142.         {
  143.             /* display the tick mark */
  144.             printf("%s",tickstr[tick_ff]);
  145.             tick_ff = 1 - tick_ff;    /* update tick flip-flop */
  146.             tick = FALSE;
  147.         }
  148.     }
  149.     wrIER(0);                               /* disable UART interrupts */
  150.     while ( !(rdLSR() & TEMT) );            /* wait for Tx FIFO to clear */
  151.     CLEAR_REGS();   /* clear RBR, LSR, MCR and IIR registers before we exit */
  152.  
  153.     /* Output error message represented by 'errflag' variable */
  154.     switch (errflag)
  155.     {
  156.     case ENDPROG:           /* keyboard hit or fatal error */
  157.         break;
  158.  
  159.     case FALSEINT:          /* IIR shows no interrupt active */
  160.         printf("\nFalse interrupt.  No UART interrupt active.\n");
  161.         break;
  162.  
  163.     case STATUSERR:         /* Line Status interrupt generated */
  164.         printf("\nLine Status interrupt.  LSR = %x\n",lsr);
  165.         printf("Byte causing LSI = %x\n",bytin);
  166.         break;
  167.  
  168.     case MISMATCH:          /* Data received did not match data expected */
  169.         printf("\nData mismatch\n");
  170.         printf("Byte expected = %x\n",--bytrd);
  171.         printf("Byte received = %x\n",bytin);
  172.         break;
  173.  
  174.     case RX_ERROR:          /* RDAI generated but DR was not set */
  175.         printf("\nError: RDAI but no DR indication\n");
  176.         break;
  177.  
  178.     case TX_ERROR:          /* THREI generated but THRE was not set */
  179.         printf("\nError: THREI but no THRE indication\n");
  180.         break;
  181.  
  182.     case IIR_ERROR:         /* Invalid IIR */
  183.         printf("\nIIR invalid\n");
  184.         break;
  185.  
  186.     case TIMEOUT:           /* Character Timeout Interrupt */
  187.         printf("\nCharacter Timeout.\n");
  188.         break;
  189.  
  190.     case TIMEOUT_ERR:       /* False Character Timeout Interrupt */
  191.         printf("\nError: False Character Timeout Interrupt.\n");
  192.         break;
  193.  
  194.     default:
  195.         break;
  196.     }                       /* end of switch */
  197.  
  198.     rstrpar();              /* restore our environment parameters */
  199.  
  200.     printf("\n\n\nEnd of program; Environment parameters restored.\n");
  201.  
  202. }  /* end of main() */
  203.  
  204. /*
  205.  *    serint(): serial port interrupt handler
  206.  */
  207.  
  208. void interrupt far serint()
  209. {
  210.     int bytecnt=0;
  211.  
  212.     /* if errflag has been set, ignore the interrupt */
  213.     if (errflag)
  214.     {
  215.         wrIER(0);
  216.         outp(PICTRL, EOI);    /* send EOI to 8259A PIC */
  217.         return;
  218.     }
  219.  
  220.     /* here's the code to handle each of the various interrupt types */
  221.     switch (iir = rdIIR())
  222.     {
  223.     case F_NOIP:      /* NO Interrupt Pending */
  224.         errflag = FALSEINT;
  225.         break;
  226.  
  227.     case F_RLST:      /* Receiver Line STatus interrupt */
  228.         lsr = rdLSR();
  229.         bytin